﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using LogLib;
using System.Reflection;
using MrtdSDKNet40;
using MrtdSDKNet40.Model;
using System.Data.Odbc;
using System.Windows.Forms;

namespace IDCardReader3in1
{
    public class SDT_IDCardReader
    {
        /// <summary>
        /// 阅读器选项
        /// </summary>
        protected IDCReaderOption _option = new IDCReaderOption();
        public IDCReaderOption Option
        {
            get { return _option; }
            set { _option = value; }
        }

        private readonly string SaveDataDirectory;

        public Encoding _encoding = System.Text.Encoding.UTF8;

        public const string TermbFilePath = "C:\\termb.lic";

        public readonly byte[] TermbLicData = new byte[]{
        0x01, 0x0A, 0x00, 0x04, 0x07, 0x21, 0xA6, 0x0B, 0x6B, 0x61, 0x30, 0xD6, 0x0A, 0xAA, 0x09, 0x64,
        0x5E, 0xF1, 0xB2, 0x38, 0xAC, 0xED, 0x48, 0x15, 0x62, 0x3B, 0xC6, 0x3F, 0x0A, 0x68, 0x0A, 0x0A,
        0x0B, 0x0A, 0x3F, 0x13, 0xBA, 0x57, 0x8E, 0xF8, 0xF0, 0x17, 0x6F, 0x44, 0x8F, 0xF7, 0xEA, 0xB4,
        0xCD, 0xD4, 0xBC, 0x32, 0xB9, 0x22, 0xE2, 0xD1, 0xEF, 0x97, 0x8A, 0x17, 0xA5, 0x1F, 0x32, 0x98,
        0xEB, 0x1D, 0x0F, 0xD1, 0x2E, 0xCF, 0xA8, 0x22, 0x09, 0x0F, 0xCF, 0x44, 0x2C, 0x3C, 0xA9, 0xC5,
        0xC5, 0x7B, 0x28, 0xDE, 0xE2, 0x16, 0xA8, 0x96, 0x51, 0x4C, 0xD1, 0x09, 0x8A, 0x2F, 0xB4, 0xFB,
        0x0F, 0xDD, 0x46, 0xB5, 0xD2, 0xF8, 0xED, 0x11, 0x16, 0x5F, 0x68, 0xD4, 0x5C, 0x11, 0x03, 0x41,
        0xB6, 0x6E, 0xE3, 0xE5, 0x40, 0xB0, 0xBC, 0xB5, 0xEF, 0x8E, 0xB2, 0x5E, 0x86, 0x3F, 0x79, 0xDD };

        public readonly string[] Nations = {
                                            "汉", "蒙古", "回", "藏", "维吾尔", "苗", "彝", "壮", "布依", "朝鲜",
                                            "满", "侗", "瑶", "白", "土家", "哈尼", "哈萨克", "傣", "黎", "傈僳",
                                            "佤", "畲", "高山", "拉祜", "水", "东乡", "纳西", "景颇", "柯尔克孜",
                                            "土", "达斡尔", "仫佬", "羌", "布朗", "撒拉", "毛难", "仡佬", "锡伯",
                                            "阿昌", "普米", "塔吉克", "怒", "乌孜别克", "俄罗斯", "鄂温克", "崩龙",
                                            "保安", "裕固", "京", "塔塔尔", "独龙", "鄂伦春", "赫哲", "门巴",
                                            "珞巴", "基诺", "其他"};

        private bool ComOpened = false;

        /// <summary>
        /// 读写器名
        /// </summary>
        private string _readerName = "";
        public string ReaderName
        {
            get { return _readerName; }
        }

        /// <summary>
        /// 自动查找
        /// </summary>
        private int _nAutoFind = 1;
        public int AutoFind
        {
            get { return _nAutoFind; }
        }

        private int _funcReturnCode = 0;
        public int FuncReturnCode
        {
            get { return _funcReturnCode; }
            set { _funcReturnCode = value; }
        }

        public bool bCreateSFZImage;//是否生成身份证正反面

        public IDCardInfo m_CardInf = new IDCardInfo();

        public List<string> listCitys = new List<string>();

        private string _errorMsg = "";

        private byte[] _data = new byte[80];

        public string ErrorMessage
        {
            get
            {
                return _errorMsg;
            }
        }

        public void SavePort()
        {
            _option.ReaderName = _readerName;
            _option.Save();
        }

        public SDT_IDCardReader()
        {
            string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
            directory = directory.Substring(6);
            SaveDataDirectory = string.Format(@"{0}\\Data", directory);
        }

       

        /// <summary>
        /// 打开读写器
        /// </summary>
        /// <param name="nPort"></param>
        /// <returns></returns>
        public bool Open(string readerName)
        {
            return ReadMrtdDocApi.Instance.InitReader(readerName, out _errorMsg);
        }

        public int Check_termb_lic()
        {
            if (!File.Exists(TermbFilePath))
            {
                using (FileStream fs = new FileStream(TermbFilePath, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(TermbLicData, 0, 128);
                }
                return 0;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 创建多级目录
        /// </summary>
        /// <param name="szPath"></param>
        /// <returns></returns>
        private bool CreateMultipleDirectory(string szPath)
        {
            //存放要创建的目录字符串
            string strDir = szPath;

            //确保以'\'结尾以创建最后一个目录
            if (strDir[strDir.Length - 1] != '\\')
            {
                strDir += ('\\');
            }

            //存放每一层目录字符串
            List<string> vPath = new List<string>();

            //一个临时变量,存放目录字符串
            string strTemp = "";

            //成功标志
            bool bSuccess = false;

            //遍历要创建的字符串
            for (int i = 0; i < strDir.Length; ++i)
            {
                //如果当前字符不是'\\'
                if (strDir[i] != '\\')
                {
                    strTemp += strDir[i];
                }
                else //如果当前字符是'\\'
                {
                    //将当前层的字符串添加到数组中
                    vPath.Add(strTemp);
                    strTemp += '\\';
                }
            }

            //遍历存放目录的数组,创建每层目录
            for (int i = 0; i < vPath.Count; i++)
            {
                //如果CreateDirectory执行成功,返回true,否则返回false
                try
                {
                    if (!Directory.Exists(vPath[i]))
                    {
                        Directory.CreateDirectory(vPath[i]);
                    }
                    bSuccess = true;
                }
                catch (Exception ex)
                {
                    Log.WriteException(ex.ToString());
                    bSuccess = false;
                }
            }
            return bSuccess;
        }

        private void ReadAndWriteFingerprintData(ref IDCardInfo info)
        {
            //写入指纹数据
            string strZWFile = string.Format("{0}\\Fingerprint.dat", SaveDataDirectory);
            if (File.Exists(strZWFile))
            {
                File.Delete(strZWFile);
            }
            if (info.uiFPMsgLen > 0)
            {
                using (FileStream fs = new FileStream(strZWFile, FileMode.Create, FileAccess.Write))
                {
                    using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
                    {
                        for (int i = 0; i < info.uiFPMsgLen; i++)
                        {
                            char[] szTmp = info.pucFPMsg[i].ToString("X2").ToCharArray();
                            sw.Write(szTmp);
                        }
                        sw.Flush();
                    }
                }
            }
        }

        /// <summary>
        /// 读取身份证信息
        /// </summary>
        /// <param name="onlyParseIDNO">只读取身份证号码</param>
        /// <returns></returns>
        public bool ReadCardInfo()
        {
            try
            {
                _errorMsg = "";

                if (!ReadMrtdDocApi.Instance.ReadCard_3in1_Win7(0, "", out MrtdSDKNet40.Model.ReadCardInfo info, out string msg))
                {
                    _errorMsg = msg;
                    return false;
                }

                int index = int.Parse(info.nationality);
                m_CardInf.m_IDnation = Nations[index - 1];
                m_CardInf.m_IDCARDNO = info.cardNo;
                m_CardInf.m_IDname = info.name;
                m_CardInf.m_IDadd = info.address;
                m_CardInf.m_IDsex = info.sex;
                m_CardInf.m_IDdepartment = info.authority;
                m_CardInf.m_IDNO = info.cardNo;
                m_CardInf.m_IDborn = info.birthDate;
                m_CardInf.m_IDdate = info.issueDate + "-" + info.ExpiryDate;
                m_CardInf.m_BmpFilePathName = "D:\\face.bmp";
                return true; ;
            }
            catch (Exception ex)
            {
                _errorMsg = ex.ToString();
                return false;
            }

        }

        private void LoadConfig()
        {
            if (!File.Exists(_option.ConfigFilePath))
            {
                _option.Save();
            }
            _option.Load();
            _readerName = _option.ReaderName;
            _encoding = Encoding.GetEncoding(_option.EncodingName);
        }

        public bool Init()
        {
            Log.AddBeginningBoundary();
            LoadConfig();
            if (!Directory.Exists(SaveDataDirectory))
            {
                //创建数据存储目录
                if (!CreateMultipleDirectory(SaveDataDirectory))
                {
                    _errorMsg = "Data文件夹创建失败: \n";
                    return false;
                }
            }
            if (Open(_readerName))
            {
                return true;
            }
            //if (AutoFind == 1)
            //{
            //    if (AutoFindPort())
            //    {
            //        if (Open(_readerName))
            //        {
            //            SavePort();
            //        }
            //    }
            //}
            return false;
        }

        public void Exit()
        {
            if (ComOpened)
            {
                //Close();
                ComOpened = false;
            }
            if (!Directory.Exists(SaveDataDirectory))
            {
                return;
            }
            try
            {
                DirectoryInfo dir = new DirectoryInfo(SaveDataDirectory);
                FileInfo[] files = dir.GetFiles();
                foreach (FileInfo file in files)
                {
                    try
                    {
                        file.Delete();
                    }
                    catch (Exception e)
                    {
                        Log.WriteException(e.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
            Log.AddEndingBoundary();
        }

        //        /// <summary>
        //        /// 加载内蒙自治区户政信息
        //        /// </summary>
        //        /// <param name="ErrMsg">错误信息  </param>
        //        /// <returns>TRUE:成功 FALSE:失败	</returns>
        //        public bool LoadLocXml(ref string ErrMsg)
        //{
        //    string strLocListXml = Path.Combine(Application.StartupPath, "LocList.xml");
        //    if(!File.Exists(strLocListXml))
        //    {
        //        ErrMsg = string.Format("缺少文件：{0}",strLocListXml);
        //        Log.WriteAsync(ErrMsg);
        //        return false;
        //    }

        //    CMarkup markup;
        //    if(!markup.Load(strLocListXml))
        //    {
        //        ErrMsg.Format(_T("加载xml文件失败：%s"),strLocListXml);
        //        Log.WriteAsync(ErrMsg);
        //        return FALSE;
        //    }
        //    CString strNodes[]={"Location","CountryRegion"};
        //    int nCount = sizeof(strNodes)/sizeof(strNodes[0]);
        //    for(int nIndex=0;nIndex<nCount;nIndex++)
        //    {
        //        if(markup.FindElem(strNodes[nIndex]))
        //        {
        //            markup.IntoElem();
        //        }
        //        else
        //        {
        //            ErrMsg.Format(_T("xml文件内容错误,请更换这个xml：%s"),strLocListXml);
        //            Log.WriteAsync(ErrMsg);
        //            return FALSE;
        //        }
        //    }
        //    CString strName;
        //    listCitys.RemoveAll();
        //    while(markup.FindElem("State"))
        //    {
        //        strName = markup.GetAttrib("Name");
        //        if(strName=="内蒙古")
        //        {
        //            m_arrCity.Add(strName);
        //            while(markup.FindChildElem("City"))
        //            {
        //                strName = markup.GetChildAttrib("Name");
        //                m_arrCity.Add(strName);
        //                markup.IntoElem();
        //                while(markup.FindChildElem("Region"))
        //                {
        //                    strName = markup.GetChildAttrib("Name");
        //                    m_arrCity.Add(strName);
        //                }
        //                markup.OutOfElem();
        //            }
        //        }
        //    }


        //    return TRUE;
        //}



        /**************************************************
        函数说明	:	生成身份证正面 背面图片
        输入参数	:	strDepatrtment: 签发机关  
                        lpFilename: 生成的图片名称   
                            lpMode: 对应CardImage.xml 的图片模板名称（Front Back）
                            lpEmpParams: 通用传参类


        函数返回值	:	0:成功		其他:返回错误值		
        **************************************************/
        //int CIDCardReader::CreateSFZHImage(CString strDepartment,LPCTSTR lpFilename,LPCTSTR lpMode,LPCTSTR lpEmpParams)
        //{
        //    CString strLog;
        //    CString strXMLFile;
        //    CFileManage fm;
        //    BOOL bMW = FALSE; //是否为蒙文

        //    strLog.Format("签发机关：[%s]!",strDepartment);
        //    Log.WriteAsync(strLog);

        //    int nIndex= strDepartment.Find("公安局");
        //    if (nIndex<=0)
        //    {
        //        nIndex= strDepartment.Find("分局");
        //    }
        //    CString department = strDepartment.Left(nIndex);
        //    department.Replace("市","");
        //    for(int nI=0;nI<m_arrCity.GetCount();nI++)
        //    {
        //        CString str = m_arrCity.GetAt(nI);
        //        if(str.Find(department)>-1 || department.Find(str) > -1)
        //        {
        //            bMW = TRUE;
        //            Log.WriteAsync(str);
        //            Log.WriteAsync(department);
        //            Log.WriteAsync("use CardImage_mw.xml");
        //            break;
        //        }
        //    }

        //    //20161214 09:42 zzj  增加简体和蒙文二种模板
        //    strXMLFile.Format("%sCardImage_jt.xml",fm.GetCurrentDllPath()); //简体模板

        //    if(bMW)
        //    {
        //        strXMLFile.Format("%sCardImage_mw.xml",fm.GetCurrentDllPath()); //蒙文模板
        //    }
        //    if (!m_pCommon->IsFileExist(strXMLFile))
        //    {
        //        strLog.Format("[%s][%s] Path Not Exist!",__FUNCTION__,strXMLFile);
        //        Log.WriteAsync(strLog);
        //        return -1;
        //    }

        //    CString strInput;

        //    if(Draw2Bmp(strXMLFile.GetBuffer() ,lpFilename ,lpEmpParams ,lpMode))
        //    {
        //        strLog.Format("[%s] %s Produce Success!",__FUNCTION__,lpFilename);
        //        Log.WriteAsync(strLog);
        //    }else
        //    {
        //        strLog.Format("[%s] %s Produce Fail!",__FUNCTION__,lpFilename);
        //        Log.WriteAsync(strLog);
        //        return -1;
        //    }

        //    if (!m_pCommon->IsFileExist(lpFilename))
        //    {
        //        strLog.Format("[%s] %s Produce Fail!",__FUNCTION__,lpFilename);
        //        Log.WriteAsync(strLog);
        //        return -1;
        //    }
        //    //DeleteFile(strStrImg);
        //}

        //int CIDCardReader::EmpReaderLoadNationConfig()
        //{
        //    CString path = m_pCommon->GetCurrentPath()+"\\Dictionary\\" + m_strNationFilename;
        //    CString strLog;
        //    if(!m_pCommon->IsFileExist(path))
        //    {
        //        strLog.Format(_T("文件不存在：%s"),path);
        //        Log.WriteAsync("EmpReaderLoadNationConfig FAIL");
        //        return -1;
        //    }
        //    if(!m_markNation.Load(path))
        //    {
        //        strLog.Format(_T("加载文件失败：%s"),path);
        //        Log.WriteAsync("EmpReaderLoadNationConfig FAIL");
        //        return -2;
        //    }
        //    return 0;
        //}

        //CString CIDCardReader::EmpGetNationCode(CString strNation)
        //{
        //    CString strCode;
        //    CString strLog;
        //    Log.WriteAsync(__FUNCTION__,"IN");
        //    strLog.Format(_T("民族：%s"),strNation);
        //    Log.WriteAsync(__FUNCTION__,strLog);
        //    m_markNation.ResetMainPos();
        //    if(m_markNation.FindChildElem("nationcode"))
        //    {
        //        m_markNation.IntoElem();
        //        while (m_markNation.FindChildElem("nation"))
        //        {
        //            CString name = m_markNation.GetChildAttrib("name");
        //            int index = strNation.Find("族");
        //            if(index!=-1)  //20170320 jy 去掉族
        //            {
        //                strNation = strNation.Left(index);
        //                Log.WriteAsync(__FUNCTION__,strNation);
        //            }
        //            //strNation.Replace(_T("族"), "");
        //            //strLog.Format(_T("去掉族：%s"),strNation);
        //            //Log.WriteAsync(__FUNCTION__,strLog);
        //            if (name == strNation)
        //            {
        //                strCode = m_markNation.GetChildAttrib("code");
        //                break;
        //            }
        //        }
        //        m_markNation.OutOfElem();
        //    }
        //    strLog.Format(_T("Code：%s"),strCode);
        //    Log.WriteAsync(__FUNCTION__,strLog);
        //    Log.WriteAsync(__FUNCTION__,"OUT");

        //    return strCode;
        //}

        //void CIDCardReader::jpg2png(CString cJpgFile, CString cPngFile, int nTolerance)
        //{
        //    CString	strInFile; 
        //    CxImage	mImage;
        //    RGBQUAD colorT;

        //    strInFile.Empty();
        //    mImage.Load(cJpgFile);

        //    int nT = nTolerance / 3;

        //    colorT.rgbBlue =250;
        //    colorT.rgbGreen =250;
        //    colorT.rgbRed = 250;

        //    mImage.SetTransIndex(mImage.GetPixelIndex(1,1));

        //    for (int i=0;i<mImage.GetWidth();i++)
        //    {
        //        for (int n=0;n<mImage.GetHeight();n++)
        //        {
        //            RGBQUAD color=	mImage.GetPixelColor(i,n);
        //            if(color.rgbBlue>(255-nT) && color.rgbGreen>(255-nT)  && color.rgbRed>(255-nT) )
        //            {
        //                mImage.SetPixelColor(i,n,colorT);
        //            }
        //        }
        //    }

        //    mImage.SetTransColor(colorT);
        //    mImage.Save(cPngFile, CXIMAGE_FORMAT_PNG);
        //}
    }
}
